<?php

class User extends CActiveRecord
{
	/**
	 * The followings are the available columns in table 'users':
	 * @var integer $id
	 * @var string  $email
	 * @var string  $password
	 * @var string  $alias
	 * @var string  $salt
	 * @var string  $secret
	 * @var integer $secrettime
	 * @var integer $created
	 * @var integer $activity
	 * @var integer $admin
	 * @var integer $status
	 */

	const STATUS_INACTIVE = 0;
	const STATUS_ACTIVE   = 1;
	const STATUS_PENDING  = 2;
	const STATUS_BANNED   = 3;
	
	const ADMIN_NO  = 0;
	const ADMIN_YES = 1;
	
	public static function model($className = __CLASS__)
	{
		return parent::model($className);
	}

	public function tableName()
	{
		return Yii::app()->getModule('user')->tables['users'];
	}

	public function rules()
	{
		return array(
			array('email', 'required', 'on' => 'admin, registration, login'),
			array('email', 'email',    'on' => 'admin, registration, login'),
			array('email', 'unique',   'on' => 'admin, registration', 'message' => UserModule::t('This email address is already taken')),
			
			array('password', 'required',     'on' => 'registration, changepassword, login'),
			array('password', 'length',       'on' => 'registration, changepassword, login', 'min' => Yii::app()->getModule('user')->settings['password']['minLength'], 'message' => UserModule::t('Invalid password (minimal length: {min} characters)', array('{min}' => Yii::app()->getModule('user')->settings['password']['minLength']))),
			
			array('alias', 'required', 'on' => 'admin, registration'),
			array('alias', 'unique',   'on' => 'admin, registration', 'message' => UserModule::t('This alias is already taken')),
			array('alias', 'length',   'on' => 'admin, registration', 'max' => Yii::app()->getModule('user')->settings['alias']['maxLength'], 'min' => Yii::app()->getModule('user')->settings['alias']['minLength'], 'message' => UserModule::t('Invalid alias (length between {min} and {max} characters)', array('{min}' => Yii::app()->getModule('user')->settings['alias']['minLength'], '{max}' => Yii::app()->getModule('user')->settings['alias']['maxLength']))),
			array('alias', 'match',    'on' => 'admin, registration', 'pattern' => '/^[a-z0-9]{1}[a-z0-9_\-\. ]+$/iu','message' => UserModule::t('Invalid characters in alias')),
			
			array('status', 'required', 'on' => 'admin'),
			array('status', 'in',       'on' => 'admin', 'range' => array(self::STATUS_INACTIVE, self::STATUS_ACTIVE, self::STATUS_PENDING, self::STATUS_BANNED)),
			
			array('admin', 'required', 'on' => 'admin'),
			array('admin', 'in',       'on' => 'admin', 'range' => array(self::ADMIN_NO, self::ADMIN_YES)),
			array('admin', 'default',                   'value' => self::ADMIN_NO),
		);
	}
	
	public function validateAuth($attribute, $params)
	{
		if(!$this->hasErrors())
		{
			$identity = new UserIdentity($this->email, $this->password);
			$identity->authenticate();
			switch($identity->errorCode)
			{
				case UserIdentity::ERROR_NONE:
					$duration = 0;
					if($this->cookie)
					{
						$duration = Yii::app()->getModule('user')->settings['cookie']['duration'];
					}
					Yii::app()->user->login($identity, $duration);
					break;
				case UserIdentity::ERROR_UNKNOWN_IDENTITY:
					$this->addError('email', UserModule::t('Authentication data is invalid'));
					break;
				case UserIdentity::ERROR_STATUS_INTACTIV:
					$this->addError('email', UserModule::t('Your account has not been activated yet'));
					break;
				case UserIdentity::ERROR_STATUS_PENDING:
					$this->addError('email', UserModule::t('Your account is still pending'));
					break;
				case UserIdentity::ERROR_STATUS_BANNED:
					$this->addError('email', UserModule::t('Your account has been banned'));
					break;
			}
		}
	}
	
	public function afterConstruct()
	{
		// echo '<pre>' . print_r($this->metaData, true) . '</pre>';
		
		parent::afterConstruct();
	}
	
	public function relations()
	{
		$relations = array();
		return $relations;
	}

	public function attributeLabels()
	{
		return array(
			'id'             => UserModule::t("ID"),
			'alias'          => UserModule::t("Alias"),
			'password'       => UserModule::t("Password"),
			'verifyPassword' => UserModule::t("Retype Password"),
			'rememberMe'     => UserModule::t("Remember Me"),
			'email'          => UserModule::t("E-mail"),
			'verifyCode'     => UserModule::t("Verification Code"),
			'salt'           => UserModule::t("Password Salt"),
			'secret'         => UserModule::t("Secret Key"),
			'secrettime'     => UserModule::t("Secret Timeout"),
			'created'        => UserModule::t("Registration Date"),
			'activity'       => UserModule::t("Last Activity"),
			'admin'          => UserModule::t("Admin"),
			'status'         => UserModule::t("Status"),
		);
	}
	
	public function scopes()
    {
        return array(
            'active'=>array(
                'condition' => 'status = ' . self::STATUS_ACTIVE,
            ),
            'inactive'=>array(
                'condition' => 'status = ' . self::STATUS_INACTIVE,
            ),
            'pending'=>array(
                'condition' => 'status = ' . self::STATUS_PENDING,
            ),
            'banned'=>array(
                'condition' => 'status = ' . self::STATUS_BANNED,
            ),
            'admin'=>array(
                'condition' =>'admin = ' . self::ADMIN_YES,
            ),
            'notsafe'=>array(
            	'select' => 'id, email, password, alias, salt, secret, secrettime, created, activity, admin, status',
            ),
        );
    }
	
	public function defaultScope()
    {
        return array(
        	'select' => 'id, email, alias, created, activity, admin, status',
        );
    }
	
	public static function itemAlias($type , $value = null)
	{
		$items = array(
			'status' => array(
				self::STATUS_INACTIVE => UserModule::t('Inactive'),
				self::STATUS_ACTIVE   => UserModule::t('Active'),
				self::STATUS_PENDING  => UserModule::t('Pending'),
				self::STATUS_BANNED   => UserModule::t('Banned'),
			),
			'admin' => array(
				self::ADMIN_NO  => UserModule::t('No'),
				self::ADMIN_YES => UserModule::t('Yes'),
			),
		);
		if(!empty($value))
		{
			return isset($_items[$type][$value]) ? $_items[$type][$value] : false;
		}
		else
		{
			return isset($_items[$type]) ? $_items[$type] : false;
		}
	}
	
	public function logActivity()
	{
		$this->activity = time();
		return $this->save();
	}
	
	public function register()
	{
		if($this->validate())
		{
			$salt = Yii::app()->getModule('user')->encrypt(microtime() . rand(1, 99999) . $this->password);
			
			$this->salt       = $salt;
			$this->password   = Yii::app()->getModule('user')->encrypt(Yii::app()->getModule('user')->salt($this->password, $salt));
			$this->secret     = '';
			$this->secrettime = 0;
			$this->created    = time();
			$this->activity   = 0;
			$this->admin      = self::ADMIN_NO;
			
			switch(Yii::app()->getModule('user')->registrationValidationType)
			{
				case UserModule::REGISTRATION_VALIDATION_TYPE_DIRECT:
					$this->status = self::STATUS_ACTIVE;
					break;
					
				case UserModule::REGISTRATION_VALIDATION_TYPE_ADMIN:
					$this->status = self::STATUS_PENDING;
					break;
					
				default:
					$this->status     = self::STATUS_INACTIVE;
					$this->secret     = Yii::app()->getModule('user')->encrypt(microtime() . rand(1, 99999) . $this->email);
					$this->secrettime = time() + Yii::app()->getModule('user')->security['timeout']['activation'];
					break;
			}
			
			return $this->save();
		}
		return false;
	}
	
	public function activate($secret)
	{
		if(($this->secret == $secret) && ($this->secrettime < (time() + Yii::app()->getModule('user')->security['timeout']['activation'])))
		{
			if($this->status == self::STATUS_INACTIVE)
			{
				if(Yii::app()->getModule('user')->registrationValidationType == UserModule::REGISTRATION_VALIDATION_TYPE_EMAIL)
				{
					$this->secret     = '';
					$this->secrettime = 0;
					$this->status     = self::STATUS_ACTIVE;
					if($this->save())
					{
						return true;
					}
					return false;
				}
				if(Yii::app()->getModule('user')->registrationValidationType == UserModule::REGISTRATION_VALIDATION_TYPE_EMAIL_ADMIN)
				{
					$this->secret     = '';
					$this->secrettime = 0;
					$this->status     = self::STATUS_PENDING;
					if($this->save())
					{
						return true;
					}
					return false;
				}
			}
		}
		return false;
	}
	
	public function changePassword($secret, $password)
	{
		if(($this->secret == $secret) && ($this->secrettime < (time() + Yii::app()->getModule('user')->security['timeout']['recovery'])))
		{
			$salt = Yii::app()->getModule('user')->encrypt(microtime() . rand(1, 99999) . $password);
			
			$this->salt       = $salt;
			$this->password   = Yii::app()->getModule('user')->encrypt(Yii::app()->getModule('user')->salt($password, $salt));
			$this->secret     = '';
			$this->secrettime = 0;
			
			return $this->save();
		}
		return false;
	}
	
	public function checkPassword($password)
	{
		if(!$this->isNewRecord)
		{
			return Yii::app()->getModule('user')->checkAgainstEncrypted(
				Yii::app()->getModule('user')->salt($password, $this->salt),
				$this->password
			);
		}
		return false;
	}
	
}
